home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / Sample Code / Snippets / Toolbox / Password / Password.c next >
Encoding:
Text File  |  1995-02-10  |  8.0 KB  |  291 lines  |  [TEXT/MPS ]

  1. //
  2. //    Password
  3. //     Sample of three different ways to implement a password dialog
  4. //
  5. //    Tim Dierks, UK Mac DTS
  6. //    August, 1991
  7. //
  8.  
  9. //    This file contains all the interesting password stuff:
  10. //   Sample.c is just the application shell, derived from CSample
  11.  
  12. #include <Types.h>
  13. #include <Memory.h>
  14. #include <Resources.h>
  15. #include <OSUtils.h>
  16. #include <Quickdraw.h>
  17. #include <Fonts.h>
  18. #include <Events.h>
  19. #include <OSEvents.h>
  20. #include <Windows.h>
  21. #include <Menus.h>
  22. #include <Dialogs.h>
  23. #include <TextEdit.h>
  24.  
  25. #include "Sample.h"
  26. #include "Password.h"
  27.  
  28. void
  29. DisplayPassword(char *password)
  30. {    DialogPtr    dlog;
  31.     short        item;
  32.     
  33.     dlog = GetNewDialog(rDisplayPasswordDialog,0L,(WindowPtr) -1L);
  34.     
  35.     ParamText(password,0L,0L,0L);
  36.     
  37.     do
  38.     {    ModalDialog(0L,&item);
  39.     } while (item != 1);            // Until the OK button gets hit
  40.     
  41.     DisposeDialog(dlog);
  42. }
  43.  
  44. char *
  45. TwoItemDialog()
  46. {    static char        password[256];
  47.     DialogPtr        dlog;
  48.     Handle            itemH;
  49.     ControlHandle    chkBox;
  50.     short            item,itemType,chkVal;
  51.     Rect            box;
  52.     Point            size;
  53.     ModalFilterUPP  twoItemFilterUPP;
  54.     
  55.     /* set up a UPP for the dialog filter */
  56.     twoItemFilterUPP = NewModalFilterProc(TwoItemFilter);
  57.     
  58.     dlog = GetNewDialog(rTwoItemDialog,0L,(WindowPtr) -1L);
  59.     
  60.     do
  61.     {    ModalDialog(twoItemFilterUPP,&item);
  62.         if (item == 4)                                            // Hide/show checkbox
  63.         {    GetDialogItem(dlog,4,&itemType,(Handle*)&chkBox,&box);    // Get check value
  64.             chkVal = !GetControlValue(chkBox);
  65.             SetControlValue(chkBox,chkVal);                            // Invert it
  66.             size.v = dlog->portRect.bottom - dlog->portRect.top;
  67.             size.h = dlog->portRect.right - dlog->portRect.left;
  68.             if (chkVal)
  69.                 size.v += 35;
  70.             else
  71.                 size.v -= 35;
  72.             
  73.             SizeWindow(dlog,size.h,size.v,true);        // Resize window
  74.         }
  75.     } while (item != 1);            // Until the OK button is hit
  76.     
  77.     GetDialogItem(dlog,3,&itemType,&itemH,&box);        // Get text from hidden dialog item
  78.     GetDialogItemText(itemH,password);
  79.     
  80.     DisposeDialog(dlog);
  81.     
  82.     DisposeRoutineDescriptor(twoItemFilterUPP);
  83.     
  84.     return password;
  85. }
  86.  
  87. pascal Boolean
  88. TwoItemFilter(DialogPtr dlog,EventRecord *event,short *itemHit)
  89. {    DialogPtr    evtDlog;
  90.     short        selStart,selEnd;
  91.     
  92.     if (event->what == keyDown || event->what == autoKey)
  93.     {    switch (event->message & charCodeMask)
  94.         {    case '\n':            // Return  (hitting return or enter is the same as hitting the OK button)
  95.             case '\003':        // Enter
  96.                 *itemHit = 1;        // OK Button
  97.                 return true;        // We handled the event
  98.             case '\t':            // Tab
  99.                 event->what = nullEvent;    // Do nothing (don't let the user tab to the hidden field)
  100.                 return false;
  101.             case '\034':        // Left arrow  (Keys that just change the selection)
  102.             case '\035':        // Right arrow
  103.             case '\036':        // Up arrow
  104.             case '\037':        // Down arrow
  105.                 return false;            // Let ModalDialog handle them
  106.             default:
  107.                 selStart = (**((DialogPeek)dlog)->textH).selStart;        // Get the selection in the visible item
  108.                 selEnd = (**((DialogPeek)dlog)->textH).selEnd;
  109.                 SelectDialogItemText(dlog,3,selStart,selEnd);                // Select text in invisible item
  110.                 DialogSelect(event,&evtDlog,itemHit);            // Input key
  111.                 SelectDialogItemText(dlog,2,selStart,selEnd);                // Select same area in visible item
  112.                 if ((event->message & charCodeMask) != '\010')    // If it's not a backspace (backspace is the only key that can affect both the text and the selection- thus we need to process it in both fields, but not change it for the hidden field.
  113.                     event->message = '•';                        // Replace with character to use
  114.                 DialogSelect(event,&evtDlog,itemHit);            // Put in fake character
  115.                 return true;
  116.         }
  117.     }
  118.     
  119.     return false;            // For all non-keyDown events
  120. }
  121.  
  122. char *
  123. DifferentFontDialog()
  124. {    static char        password[256];
  125.     DialogPtr        dlog;
  126.     Handle            itemH;
  127.     short            item,itemType,font;
  128.     Rect            box;
  129.     UserItemUPP     chicagoTextItemUPP;
  130.     
  131.     /* create the UPP for our ChicagoTextItem userItem */
  132.     chicagoTextItemUPP = NewUserItemProc(ChicagoTextItem);
  133.     
  134.     GetFNum("\p.Pwd",&font);        // Get the font number for our password font (it begins with a period, so AppendResMenu won't add it)
  135.     SetDialogFont(font);                // Use this font for static and edit text items in further dialogs
  136.     
  137.     dlog = GetNewDialog(rDifferentFontDialog,0L,(WindowPtr) -1L);
  138.     
  139.     GetDialogItem(dlog,3,&itemType,&itemH,&box);            // Because SetDialogFont affects static items, too, we've got to use user items to draw our prompts
  140.     SetDialogItem(dlog,3,itemType,(Handle)chicagoTextItemUPP,&box);
  141.     GetDialogItem(dlog,4,&itemType,&itemH,&box);
  142.     SetDialogItem(dlog,4,itemType,(Handle)chicagoTextItemUPP,&box);
  143.     
  144.     do
  145.     {    ModalDialog(0L,&item);
  146.     } while (item != 1);            // Until the OK button is hit
  147.     
  148.     GetDialogItem(dlog,2,&itemType,&itemH,&box);        // Get text from TE item
  149.     GetDialogItemText(itemH,password);
  150.     
  151.     DisposeDialog(dlog);
  152.     
  153.     SetDialogFont(0);        // Set the dialog font back to the System font
  154.     
  155.     DisposeRoutineDescriptor(chicagoTextItemUPP);
  156.     
  157.     return password;
  158. }
  159.  
  160. pascal void
  161. ChicagoTextItem(WindowPtr wind,short item)
  162. {    short        fontStore,sizeStore;
  163.     Handle        itemH;
  164.     short        itemType;
  165.     Rect        box;
  166.     char        *text;
  167.     
  168.     SetPort(wind);
  169.     
  170.     fontStore = wind->txFont;    // Remember the current font & size
  171.     sizeStore = wind->txSize;
  172.     
  173.     TextFont(0);        // Set to default System font & size
  174.     TextSize(0);
  175.     
  176.     GetDialogItem(wind,item,&itemType,&itemH,&box);
  177.     
  178.     if (item == 3)            // These strings would probably be in a resource or somesuch in an actual program.
  179.         text = "\pPlease enter your password:";
  180.     if (item == 4)
  181.         text = "\pSpecial Font Password Dialog";
  182.     
  183.     TETextBox(text+1,*text,&box,teJustLeft);    // Draw the prompt
  184.     
  185.     TextFont(fontStore);        // Restore the font & size
  186.     TextSize(sizeStore);
  187. }
  188.  
  189. char *
  190. InternalBufferDialog()
  191. {    static char        password[256];
  192.     DialogPtr        dlog;
  193.     short            item;
  194.     ModalFilterUPP  internalBufferFilterUPP;
  195.     
  196.     /* create the UPP for the InternalBufferFilter */
  197.     internalBufferFilterUPP = NewModalFilterProc(InternalBufferFilter);
  198.     
  199.     dlog = GetNewDialog(rInternalBufferDialog,0L,(WindowPtr) -1L);
  200.     
  201.     *password = '\0';                    // Zero out the buffered password
  202.     SetWRefCon(dlog,(long)password);    // Stash the buffer's address
  203.     
  204.     do
  205.     {    ModalDialog(internalBufferFilterUPP,&item);
  206.     } while (item != 1);            // Until the OK button is hit
  207.     
  208.     DisposeDialog(dlog);
  209.     
  210.     DisposeRoutineDescriptor(internalBufferFilterUPP);
  211.     
  212.     return password;
  213. }
  214.  
  215. pascal Boolean
  216. InternalBufferFilter(DialogPtr dlog,EventRecord *event,short *itemHit)
  217. {    char    key;
  218.     short    start,end;
  219.     char    *buffer;
  220.     
  221.     if (event->what != keyDown && event->what != autoKey)
  222.         return false;                // We don't want to deal with them
  223.     
  224.     key = event->message & charCodeMask;
  225.     
  226.     switch (key)
  227.     {    case '\n':            // Return
  228.         case '\003':        // Enter
  229.             *itemHit = 1;        // OK Button
  230.             return true;        // We handled the event
  231.         case '\t':            // Tab
  232.         case '\034':        // Left arrow
  233.         case '\035':        // Right arrow
  234.         case '\036':        // Up arrow
  235.         case '\037':        // Down arrow
  236.             return false;        // Let ModalDialog handle them
  237.         default:            // Everything else falls through to be dealt with
  238.             break;            //    below
  239.     }
  240.     
  241.     start = (**((DialogPeek)dlog)->textH).selStart;    // Get the current selection
  242.     end = (**((DialogPeek)dlog)->textH).selEnd;
  243.     
  244.     buffer = (char*)GetWRefCon(dlog);        // Get the buffer's address
  245.     
  246.     if (start != end)                    // If there's a selection, delete it
  247.         DeleteRange(buffer,start,end);
  248.     
  249.     if (key == '\010')    // Backspace
  250.     {    if (start != 0)
  251.             DeleteRange(buffer,start-1,start);    // Delete the character to the left
  252.     }
  253.     else
  254.     {    InsertChar(buffer,start,key);        // Insert the real key into the buffer
  255.         event->message = '*';                // Character to use in field
  256.     }
  257.     
  258.     return false;         // Let ModalDialog insert the fake char
  259. }
  260.  
  261. void
  262. DeleteRange(char *buffer,short start,short end)
  263. {    register char    *src,*dest,*last;
  264.     
  265.     last = buffer + *buffer;
  266.     
  267.     src = buffer + end + 1;
  268.     dest = buffer + start + 1;
  269.     
  270.     while (src <= last)            // Shift character to the left over the removed characters
  271.         *(dest++) = *(src++);
  272.     
  273.     (*buffer) -= (end-start);    // Adjust the buffer's length
  274. }
  275.  
  276. void
  277. InsertChar(char *buffer,short pos,char c)
  278. {    register short    index,len;
  279.     
  280.     len = *buffer;
  281.     
  282.     if (len == 0xFF)        // if the string is full, return
  283.         return;
  284.     
  285.     for (index = len;index > pos;index--)    // Shift characters to the right to make room
  286.         buffer[index+1] = buffer[index];
  287.     
  288.     buffer[pos+1] = c;        // Fill in the new character
  289.     
  290.     (*buffer)++;            // Add one to the length of the string
  291. }